/**
 * 服务
 * */
package org.zmhhxl.user.service.impl;

import lombok.AllArgsConstructor;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.zmhhxl.api.auth.domain.entity.Role;
import org.zmhhxl.api.auth.domain.entity.ThirdPartyUser;
import org.zmhhxl.api.auth.domain.entity.UserInfo;
import org.zmhhxl.api.auth.domain.entity.dto.UserRoleDTO;
import org.zmhhxl.api.auth.domain.entity.dto.UserThirdPartyUserDTO;
import org.zmhhxl.common.core.domain.Result;
import org.zmhhxl.common.core.enumate.Enabled;
import org.zmhhxl.user.domain.repository.RoleRepository;
import org.zmhhxl.user.domain.repository.ThirdPartyUserRepository;
import org.zmhhxl.user.domain.repository.UserInfoRepository;
import org.zmhhxl.user.domain.repository.UserRoleRepository;
import org.zmhhxl.user.service.UserInfoService;

import java.util.Optional;
import java.util.Set;

@Service
@AllArgsConstructor
public class JpaUserInfoServiceImpl implements UserInfoService {
   private static final PasswordEncoder delegatingPasswordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
   private final UserInfoRepository userInfoRepository;
   private final UserRoleRepository userRoleRepository;
   private final ThirdPartyUserRepository thirdPartyUserRepository;
   private final RoleRepository roleRepository;
   //private final UserInfoMapper userInfoMapper;

   /**
    * Find by username user info.
    *
    * @param username the username
    * @return the user info
    */
   @Override
   //@Transactional(readOnly = true)
   public UserInfo findByUsername(String username) {
      return userInfoRepository.findByUsername(username).orElseThrow(() -> new RuntimeException("用户不存在"));
   }


//   @Override
//   public UserInfo save(UserInfoDTO userInfoDTO) {
//      UserInfo userInfo = userInfoMapper.toEntity(userInfoDTO); //new UserInfo();
//      //userInfoMapper.toUserInfo(userInfoDTO, userInfo);
//      userInfo.setPassword(delegatingPasswordEncoder.encode(userInfo.getPassword()));
//      if (userInfo.getGender() == null) {
//         userInfo.setGender(Integer.valueOf(Gender.UNKNOWN.val()));
//      }
//      if (userInfo.isEnabled() == false) {  //enabled
//         userInfo.setEnabled(Boolean.valueOf(Enabled.ENABLE.val()));
//      }
//      return userInfoRepository.save(userInfo);
//   }

   @Override
   public Result<UserInfo> save(UserInfo userInfo) {
//      UserInfo target = userInfoRepository.findById(userInfo.getId())
//            .orElseThrow(()->new RuntimeException("用户不存在"));
//      this.userInfoMapper.mergeIgnorePasswordAndAuthorities(userInfo, target);
//      this.userInfoRepository.flush();
      UserInfo target = this.userInfoRepository.save(userInfo);
      return Result.success(target);
   }

   /**
    * Update.
    *
    * @param userInfo the user info
    */
   @Override public void update(UserInfo userInfo) {
      UserInfo target = userInfoRepository.findById(userInfo.getId())
            .orElseThrow(()->new RuntimeException("用户不存在"));
      //this.userInfoMapper.mergeIgnorePasswordAndAuthorities(userInfo, target);

      this.userInfoRepository.flush();
   }

   /**
    * Delete by id.
    *
    * @param userId the user id
    */
   @Override
   public void deleteById(Long userId) {
      this.userInfoRepository.deleteById(userId);
   }

   /**
    * Enable.
    *
    * @param userId the user id
    */
   @Override public void enable(String userId) {
       this.userInfoRepository.findById(Long.valueOf(userId))
             .ifPresent(userInfo -> {
                userInfo.setEnabled(Boolean.valueOf(Enabled.ENABLE.val()));
                this.userInfoRepository.save(userInfo);
             });
   }

   /**
    * Find by id user info.
    *
    * @param userId the user id
    * @return the user info
    */
   @Override
   //@Transactional(readOnly = true)
   public Optional<UserInfo> findById(Long userId) {
      return this.userInfoRepository.findById(userId);
   }

   /**
    * Find by id user info.
    *
    * @param userId the user id
    * @return the user info
    */
   //@Override public UserInfo findById(String userId) {
//      return null;
//   }

   /**
    * Bind roles.
    *
    * @param userRoleDTO the user role dto
    */
   @Override public void bindRoles(UserRoleDTO userRoleDTO) {
      UserInfo userInfo = userInfoRepository.findById(userRoleDTO.getUserId())
            .orElseThrow(()->new RuntimeException("用户不存在"));
      Set<Role> roles = roleRepository.findAllByIdIn(userRoleDTO.getRoleIds());
      userInfo.setAuthorities(roles);
      this.userInfoRepository.flush();
   }

   @Override public void bindRoles(Long userId, Long roleId) {

   }

   @Override public void unbindRoles(UserRoleDTO userRoleDTO) {

   }

   @Override public void unbindRoles(Long userId, Long roleId) {

   }

   @Override public void bindThirdPartyUser(UserThirdPartyUserDTO userThirdPartyUserDTO) {
        UserInfo userInfo = userInfoRepository.findById(userThirdPartyUserDTO.getUserId())
              .orElseThrow(()->new RuntimeException("用户不存在"));
        Set<ThirdPartyUser> thirdPartyUsers = thirdPartyUserRepository.findAllByIdIn(userThirdPartyUserDTO.getThirdPartyUserIds());
        userInfo.setThirdPartyUsers(thirdPartyUsers);
        this.userInfoRepository.flush();
   }

   @Override public void bindThirdPartyUser(Long userId, Long thirdPartyUserId) {

   }

   @Override public void unbindThirdPartyUser(UserThirdPartyUserDTO userThirdPartyUserDTO) {

   }

   @Override public void unbindThirdPartyUser(Long userId, Long thirdPartyUserId) {

   }
}
